// Indexador.  SequencialReadPages. v. 0.1
// Autor:  MC e Baggio
// Data: 11/06/2008

#include <iostream>
#include <fstream>
#include <cstdio>
#include <sstream>

#include "SequencialReadPages.h"

using namespace std;


SequencialReadPages::SequencialReadPages(){
	tagInitSize = 16; //15 + \n
	tagEndSize = 17;  //16 + \n
	maxNumFiles = 298;  // S� at� ID_(maxNumFiles)...  
	//Abre Arquivo
	arquivoDePaginas = fopen64(fileName(0).c_str(), "r+");
	if(arquivoDePaginas == NULL){
		cout << "Erro ao tentar abrir o arquivo: arquivoDePaginas " << endl;
		exit(1);
	}
	fseeko64(arquivoDePaginas, 0, SEEK_END);
	fileSize = ftello64(arquivoDePaginas);
	endOfCurrentFile = false;
	infoTable = new _infoTable;
	infoTable->file_ID = 0;  //comeca no 0
	tempBufferSize = 512*1024;
	totalReal = 0;
	tempBuffer = new char [tempBufferSize];
	stringBuffer = "";
	
	infoTable->contNumPages = 0;
	
	next();
}

SequencialReadPages::~SequencialReadPages(){
	delete [] tempBuffer;
	delete infoTable;
	fclose(arquivoDePaginas);
}

string SequencialReadPages::getPageURL(){
	return pageURL;
}

string SequencialReadPages::getPageHTML(){
	return pageHTML;
}


//!!!!!!!!!!!!!!!!!!!!!!!!  v. 0.1
//Falta arrumar fseek e leitura de multiplas paginas em um mesmo bloco !
//Coloar backup
//!!!!!!!!!!!!!!!!!!!!!!!!
bool SequencialReadPages::next(){
	bool boolTrap;
	bool fileID_status;
	boolTrap = nextTrap();
	if(boolTrap == false){
		do{
			infoTable->file_ID+=2; //vai de dois em dois
			fileID_status = reloadFile(infoTable->file_ID);
			boolTrap = nextTrap();
			if(boolTrap) return true;
		}while(fileID_status);
	}else return true;
	return false;
}


bool SequencialReadPages::nextTrap(){
	if(endOfCurrentFile) return false;
	if(fileSize == 0) return false;
	
	infoTable->contNumPages++;
	
	//ainda nao bom, versao 0.1 ainda	
	fseek(arquivoDePaginas, infoTable->nextToRead, SEEK_SET ); //posiciona a partir do inicio 
	infoTable->nextToRead = ftello64(arquivoDePaginas);           // nao bom, vai mudar depois
	unsigned int totalNextRead; //determina quanto pode ler
	while( ftello64(arquivoDePaginas) < fileSize){ //for�a a ler at� o final do arquivo
		if( (fileSize - infoTable->nextToRead) > tempBufferSize) totalNextRead = tempBufferSize;
		else	totalNextRead = (fileSize - infoTable->nextToRead);
		totalReal = fread(tempBuffer, sizeof(char)*totalNextRead, 1, arquivoDePaginas);
		if(totalReal == 1) break;
	}
	if(totalReal != 1){
		//fim do arquivo
//		cout << "Size: " << fileSize << endl;
//		cout << "tempBufferSize: " << tempBufferSize << endl;
//		cout << "totalNextRead: " << totalNextRead << endl;
//		cout << "totalReal: " << totalReal << endl;
//		cout << "Ftell: " << infoTable->nextToRead << endl;
		endOfCurrentFile = true;
		return false;
	}	
	
	stringBuffer.clear();
	posTagInit = 0;
	posTagEnd = 0;
	stringBuffer.append(tempBuffer, totalNextRead);
	
	//Procura na p�gina os Tags especiais que delimitam as paginas
	// a saber:  <TetraTAGnatha> e </TetraTAGnatha>
	posTagInit = stringBuffer.find("<TetraTAGnatha>", 0);
	if(posTagInit == stringBuffer.npos){
		cout << "Provavelmente acabou o arquivo (1).... " << endl;
		endOfCurrentFile = true;
	}
	
	posTagEnd = stringBuffer.find("</TetraTAGnatha>", 0);
	if(posTagInit == stringBuffer.npos){
		cout << "Arquivo (ou Bloco lido) provavelmente comrompido... tag de fechamento nao encontrada" << endl;
		endOfCurrentFile = true;
	}
	
	pageURL = stringBuffer.substr(posTagInit + tagInitSize, posTagEnd - posTagInit - tagInitSize);
	
	//procura pelo inicio do proximo bloco, delimitando o corpo do HTML
	nextTagInit = stringBuffer.find("<TetraTAGnatha>", posTagEnd+tagEndSize);
	
	if(nextTagInit == stringBuffer.npos){
		cout << "Provavelmente acabou o arquivo (2).... " << endl;
		endOfCurrentFile = true;
	}
	
	if(nextTagInit <= posTagEnd){
		cout << "Ce ta loko ? " << endl;
		endOfCurrentFile = true;
	}
	
	pageHTML = stringBuffer.substr(posTagEnd + tagEndSize,(nextTagInit-posTagEnd-tagEndSize));
	//atualiza a ultima pos lida para proxima leitura
	if(!endOfCurrentFile ){
		infoTable->lastReaded = infoTable->nextToRead;
		infoTable->nextToRead += nextTagInit; //pq as posicoes das tags sempre comecam do zero
	}
	return true;
}

string SequencialReadPages::fileName(int id){
	string nameFile = "/work/disco/ID_";
	stringstream convert;
	convert << id;
	nameFile = nameFile + convert.str();
	return nameFile;
}

bool SequencialReadPages::reloadFile(int id){
//	cout << " ************************************$*************************************************** " << endl;
//	cout << " --->  ID: " << id << endl;
//	cout << " *************************************************************************************** " << endl;
	if(id < 0 || id > maxNumFiles) return false;

	
	if(arquivoDePaginas != NULL) fclose(arquivoDePaginas);
	arquivoDePaginas = fopen64(fileName(id).c_str(), "r+");
	if(arquivoDePaginas == NULL){
		cout << "Erro ao tentar abrir o arquivo: arquivoDePaginas " << endl;
		cout << "Arquivo nome: " << fileName(id).c_str() << endl;
		exit(1);
	}

	fseeko64(arquivoDePaginas, 0, SEEK_END);
	fileSize = ftello64(arquivoDePaginas);
	
	infoTable->nextToRead = 0;
	infoTable->contNumPages = 0;
	endOfCurrentFile = false;
	
	return true;
}
